home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / pctj0187.arc / EGAFONT.ASM < prev    next >
Assembly Source File  |  1987-01-28  |  10KB  |  377 lines

  1.     page    80,132
  2.     title    egafont -- ega font routines for Turbo Pascal
  3. ;
  4. ;    2 entry points
  5. ;    [0]    1. EGAstring(s : string; x, y, color, direction:  
  6. ;            integer; VAR f: fontrecord);
  7. ;    [3]    2. EGAinitfont(f: fontarray);
  8. ;
  9. ;    Because this runs under Turbo Pascal, no direct references
  10. ;    are made to the code segment. However registers are set up to
  11. ;    provide access to assembled tables when needed.
  12. ;        John T. Cockerham, November 1986
  13. ;    Font table layout
  14. fontptr        equ    0    ;pointer to the actual font
  15. fonthit        equ    4    ;height of characters
  16. ftype        equ    6    ;type of font; 0=fixed
  17. fwidth        equ    8    ;width of characters
  18. FontTbSize    equ    10
  19. ;
  20. videoio        equ    10H    ;BIOS interrupt vector
  21. FontInfo    equ    1130H    ;Font Information Request code
  22. StdFont        equ    0200H    ;Standard Font Info Code
  23. DblFont        equ    0300H    ;Double Dot Info Code
  24. GDCSet        equ    00H    ;GDC set/reset register
  25. GDCEnab        equ    01H    ;GDC enable set/reset
  26. GDCAlu        equ    03H    ;GDC Alu operation and shift
  27. GDCMask        equ    08H    ;GDC bit mask
  28. GDC        equ    03CEH    ;The GDC data register pair
  29. ;
  30. FontWidth    equ    8    ;The width of all fonts is 8
  31. Horiz        equ    0    ;Horizontal directions constant
  32. Vert_Up        equ    1    ;Vertical up going direction
  33. ScreenWidth    equ    80    ;Screen is 80 columns wide
  34. ;
  35. ;    stack layout for string and character calls
  36. ;
  37. stx    equ    [bp+20]
  38. x0    equ    word ptr [bp+18]
  39. y0    equ    word ptr [bp+16]
  40. color    equ    word ptr [bp+14]
  41. direct    equ    word ptr [bp+12]
  42. op    equ    word ptr [bp+10]
  43. font    equ    dword ptr [bp+6]
  44. retx    equ    word ptr [bp+4]
  45. oldds    equ    word ptr [bp+2]
  46. oldbp    equ    word ptr [bp]
  47. x1    equ    word ptr [bp-2]
  48. y1    equ    word ptr [bp-4]
  49. x2    equ    word ptr [bp-6]
  50. y2    equ    word ptr [bp-8]
  51. csx    equ    word ptr [bp-10]
  52. pts    equ    word ptr [bp-12]
  53. fp    equ    [bp-16]        ;address pointer dd here
  54. j    equ    word ptr [bp-18]
  55. b1    equ    word ptr [bp-20]
  56. b2    equ    word ptr [bp-22]
  57. stpt    equ    word ptr [bp-24]
  58. c1    equ    word ptr [bp-26]
  59. ;
  60. ;    entry points
  61. ;
  62. egafont    segment    'code'
  63.     assume    cs:egafont,es:nothing,ds:nothing 
  64.     jmp    dostr1
  65.     jmp    initf1
  66.     db    'EGAFONT'    ;So it can be found
  67. ;
  68. ;mask1 is the masks for the left byte
  69. ;bittab is the bit table for setting dots
  70. ;
  71. mask1    db    0ffh, 07fh, 03fh, 01fh, 00fh, 007h, 003h, 001h
  72. bittab    db    080h, 040h, 020h, 010h, 008h, 004h, 002h, 001h
  73. ;    
  74. ;    Do string 
  75. ;
  76. dostr    proc    near
  77. dostr1:    push    ds
  78.     push    bp        ;set up the stack
  79.     mov    bp,sp        ;new stack pointer
  80.     sub    sp,30        ;carve out space on the stack
  81.     call    dost2        ;get offset into code segment
  82. dost2    proc    near
  83. dost2    endp            ;dummy procedure segment
  84. dost3:    pop    ax        ;this is our return address
  85.     sub    ax,offset dost3    ;now we have start of the segment
  86.     mov    csx,ax        ;in case we need it
  87.     mov    stpt,0        ;this is our string pointer
  88. str1:
  89.     inc    stpt        ;top of character loop
  90.     les    bx,stx        ;get the string address
  91.     mov    al,es:[bx]    ;this is the length of the string
  92.     xor    ah,ah        ;zap the high byte
  93.     cmp    stpt,ax        ;look at where we are in the string
  94.     jbe    strx1        ;all done?
  95.     jmp    strxt
  96. strx1:    add    bx,stpt        ;this is the character
  97.     mov    al,es:[bx]    ;
  98.     xor    ah,ah        ;zot the byte
  99.     mov    c1,ax        ;the character is in hand
  100.     les    bx,font        ;get the font pointer
  101.     mov    ax,es:fonthit[bx]
  102.     mov    pts,ax        ;height of characters
  103. ;
  104. ;    here calculate the font pointer 
  105. ;
  106.     mul    c1        ;this makes the offset
  107.     lds    si,es:fontptr[bx]; this is the start of the font
  108.     add    si,ax        ;this is the start of the character
  109.     mov    fp,si
  110.     mov    fp[2],ds    ;save the point for a moment
  111. ;
  112. ;    this is the main painting loop    
  113. ;
  114.     mov    j,1        ;start on the 1 line of the font
  115. dost6:    mov    ax,x0
  116.     mov    x1,ax        ;p1 := p0
  117.     mov    ax,y0
  118.     mov    y1,ax        
  119. dost7:    lds    si,dword ptr fp    ;get the font point
  120.     inc    word ptr fp    ;move the font point
  121.     mov    dl,[si]        ;this is the actual font byte 
  122.     xor    dh,dh        ;clean up the high byte
  123. ;
  124.     mov    ax,direct    ;branch on direction
  125.     cmp    ax,Horiz    ;handle the regular case
  126.     jne    dostup    
  127.     call    fbhor        ;horizontal painting
  128.     inc    y0        ;bump for the next "line"
  129.     jmp    short dostlnx
  130. dostup:    call    fbvert
  131.     mov    ax,direct    ;update the point the next font line
  132.     cmp    ax,Vert_Up    ;this is the up direction
  133.     jne    dost11
  134.     inc    x0
  135.     jmp    short dostlnx
  136. dost11:    dec    x0
  137. dostlnx:
  138.     inc    word ptr j    ;j is the font pointer
  139.     mov    ax,j        ;get the pointer for comparison
  140.     cmp    ax,pts        ;another point?
  141.     ja    dostx        ;yes again
  142.     jmp    dost6
  143. ;
  144. ;    move the pointer to the next position in the string
  145. ;
  146. dostx:    mov    ax,direct
  147.     mov    bx,FontWidth
  148.     mov    cx,pts
  149.     cmp    ax,Horiz    ;check the direction move accordingly
  150.     jne    dost13
  151.     add    x0,bx        ;move across the screen
  152.     sub    y0,cx        ;and to the top of the character box
  153.     jmp    str1
  154. dost13:    cmp    ax,Vert_Up    ;this is the up direction
  155.     jne    dost14
  156.     sub    y0,bx        ;move up the screen
  157.     sub    x0,cx        ;and to the top of the char box
  158.     jmp    str1        ;another character
  159. dost14:    add    y0,bx        ;Vertical Down default
  160.     add    x0,cx        ;the next box is down the screen
  161.     jmp    str1        ;get the next character
  162. ;
  163. ;    clean up and exit
  164. ;
  165. strxt:    mov    sp,bp        ;dissolve the stack
  166.     pop    bp
  167.     pop    ds
  168.     ret    18        ;drop 18 bytes off the stack
  169. dostr    endp
  170. ;
  171. ;    passed one pointer to the font information array
  172. ;
  173. farray    equ    dword ptr [bp+4]
  174. initf    proc    near
  175. initf1:    
  176.     push    bp
  177.     mov    bp,sp        ;stack preamble
  178. ;        get the first font information
  179.     push    bp        ;Bios will clobber our bp
  180.     mov    ax,FontInfo    ;information request
  181.     mov    bx,StdFont    ;on the 8 by 14 font
  182.     int    videoio        ;
  183.     mov    ax,bp        ;get the returned bp pointer
  184.     pop    bp        ;es:ax now has the font address
  185.     lds    di,farray    ;ds:di points to start of the array
  186.     mov    fontptr[di],ax        ;the offset
  187.     mov    fontptr[di+2],es    ;and the segment
  188.     mov    word ptr fonthit[di],14    ;this is the size in points
  189.     mov    word ptr ftype[di],0    ;this is a fixed font
  190.     mov    word ptr fwidth[di],8    ;and it is 8 pixels wide
  191. ;        get the double dot font
  192.     push    bp        ;save the bp
  193.     mov    ax,FontInfo    ;request information
  194.     mov    bx,DblFont    ;on the double dot font
  195.     int    videoio        ;ask for it from the bios
  196.     mov    ax,bp        ;get the pointers
  197.     pop    bp        ;and recover bp
  198.     lds    di,farray    ;get the array pointer
  199.     add    di,FontTbSize    ;move to the next entry in the array
  200.     mov    fontptr[di],ax    ;the offset
  201.     mov    fontptr[di+2],es;and the segment
  202.     mov    word ptr fonthit[di],8    ;this is the size in points
  203.     mov    word ptr ftype[di],0    ;this is a fixed font
  204.     mov    word ptr fwidth[di],8    ;and it is 8 pixels wide
  205.     pop    bp
  206.     ret    4        ;drop 4 bytes off of the stack
  207. initf    endp
  208. ;
  209. ;    paint a horizontal byte
  210. ;        dx = font byte
  211. fbhor    proc    near
  212.     mov    ax,x1        ;calculate the various offsets
  213.     and    ax,07h        ;the offset into the bitstring
  214.     mov    si,ax        ;and get set to index
  215.     mov    cx,ax
  216.     ror    dl,cl        ;this rotates it
  217.     xor    dh,dh        ;for security
  218. ;
  219.     add    si,csx        ;this is the cseg offset
  220.     mov    al,cs:Mask1[si]    ;get the particular mask byte
  221.     mov    cx,ax
  222.     and    cx,dx        ;this is one form of the character
  223.     mov    b1,cx        ;the left portion
  224.     not    ax
  225.     and    ax,dx        ;this is the right portion
  226.     mov    b2,ax        
  227. ;
  228.     mov    ax,x1        ;get set to calculate the EGA address
  229.     mov    x2,ax        ;from points x2 and y2
  230.     mov    ax,y1        ;in the stack
  231.     mov    y2,ax        
  232.     call    egacalc        ;get es:di set to the EGA buffer
  233.     mov    ax,color    ;fix the set/reset mechanism
  234.     mov    bx,0fh        ;in all planes to the color
  235.     call    setreset    ;
  236.     mov    ax,op        ;now get the ALU all set up
  237.     call    egaalu        ;done
  238. ;
  239. ;    pixel string straddles two bytes
  240. ;
  241.     mov    ax,b1        ;first mask
  242.     call    egamask
  243.     mov    al,es:[di]    ;get the byte latched in
  244.     mov    es:[di],al    ;latches and set reset do all
  245.     inc    di        ;move to the next byte
  246.     mov    ax,b2
  247.     call    egamask        ;this is the next byte
  248.     mov    al,es:[di]
  249.     mov    es:[di],al    ;all done with both bytes
  250. ;
  251. ;    all done clean up
  252. ;
  253.     mov    ax,0ffH        ;reset the mask
  254.     call    egamask
  255.     xor    ax,ax
  256.     xor    bx,bx
  257.     call    setreset
  258.     xor    ax,ax
  259.     call    egaalu        ;reset the hardware
  260.     ret
  261. fbhor    endp
  262. ;
  263. ;    Paint Vertical Byte depends on point access routines
  264. ;    paint the byte at point p1
  265. ;
  266. fbvert    proc    near
  267.     mov    ax,x1        ;make copy of the point
  268.     mov    x2,ax
  269.     mov    ax,y1
  270.     add    ax,FontWidth    ;start off 
  271.     mov    y2,ax        ;from the character
  272.     mov    cx,FontWidth    ;get set to loop
  273.     mov    bx,080H        ;start from the left edge of the byte
  274. fbv1:    mov    ax,dx        ;get the font byte
  275.     and    ax,bx        ;is the bit set
  276.     jz    fbv2        ;no then skip this drawing
  277.     push    dx
  278.     push    bx
  279.     push    cx
  280.     call    dot        ;draw the dot at point #2
  281.     pop    cx
  282.     pop    bx        ;the dot is drawn
  283.     pop    dx
  284. fbv2:    
  285.     shr    bx,1        ;look at the next bit
  286.     cmp    direct,Vert_Up    ;do we bump or drop to the next point
  287.     jnz    fbv3
  288.     dec    y2        ;this is painting up
  289.     jmp    short fbv4
  290. fbv3:    inc    y2
  291. fbv4:    loop    fbv1
  292.     ret
  293. fbvert    endp
  294. ;
  295. ;    Set EGA GDC Bitmask
  296. ;        ax = mask value
  297. egamask    proc    near
  298.     mov    ah,al        ;get value in high byte
  299.     mov    al,GDCMask    ;set up the IO instruction
  300.     mov    dx,GDC
  301.     out    dx,ax        ;put it out
  302.     ret
  303. egamask    endp
  304. ;
  305. ;    Set EGA set reset registers
  306. ;        ax = value to fill; bx = planes
  307. setreset proc    near
  308.     mov    ah,al        ;get the value in the right place
  309.     mov    al,GDCSet    ;point to the GDC set register
  310.     mov    dx,GDC        ;set up IO instruction
  311.     out    dx,ax        ;first half of instruction
  312.     mov    ah,bl        ;these are the enable bits
  313.     mov    al,GDCEnab    ;this in the enable register
  314.     out    dx,ax        ;talk to the device
  315.     ret
  316. setreset endp
  317. ;
  318. ;    Set EGA GDC Alu operation and shift
  319. ;
  320. egaalu    proc    near
  321.     mov    ah,al        ;get value in high byte
  322.     mov    al,GDCAlu    ;set up the IO instruction
  323.     mov    dx,GDC
  324.     out    dx,ax        ;put it out
  325.     ret
  326. egaalu    endp
  327. ;
  328. ;    calculate EGA address
  329. ;        x2, y2 in the stack 
  330. egacalc    proc    near
  331.     mov    ax,y2
  332.     mov    cx,ScreenWidth
  333.     mul    cx        ;get the offset
  334.     mov    bx,x2        ;now figure offset within the row
  335.     mov    cx,3
  336.     shr    bx,cl        ;strip down to a byte address
  337.     add    ax,bx
  338.     mov    di,ax        ;di is now set
  339.     mov    ax,0a000H    ;this is the screen segment
  340.     mov    es,ax
  341.     nop
  342.     ret
  343. egacalc    endp
  344. ;
  345. ;    dot -- draw a dot
  346. ;
  347. dot    proc     near
  348.     call    egacalc        ;get es:di to point to the byte
  349.     mov    ax,x2        ;figure out the bit offset
  350.     and    ax,07H        ;this is the offset in the byte
  351.     mov    bx,csx        ;get set to address ourselves
  352.     add    bx,ax        ;now point within the bittab table
  353.     mov    ah,cs:bittab[bx];get the mask value in ax
  354.     mov    al,GDCMask    ;isolate to the bit in question
  355.     mov    dx,GDC        ;talk to the GDC
  356.     out    dx,ax        ;the mask is set
  357.     mov    ax,op        ;set up the operation
  358.     mov    ah,al        ;get to the upper byte
  359.     mov    al,GDCAlu    ;this is the ALU
  360.     out    dx,ax        ;done setting operation
  361.     mov    ax,color    ;this is the color
  362.     mov    bx,0FH        ;into set/reset
  363.     call    setreset
  364.     mov    ch,es:[di]    ;get the ram byte latched in
  365.     mov    byte ptr es:[di],0FFH;set reset fills in the color
  366.     xor    ax,ax        ;turn off the ALU
  367.     call    egaalu
  368.     xor    ax,ax        ;and set reset
  369.     xor    bx,bx
  370.     call    setreset
  371.     mov    ax,0ffh        ;now turn on the bitmap
  372.     call    egamask
  373.     ret            ;all done
  374. dot    endp    
  375. egafont    ends    
  376.     end
  377.